package org.zfes.snowier.cloud.zbss.cms.content.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.zfes.snowier.core.data.DataSet;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.zfes.snowier.core.util.ZBeanUtil;
import org.zfes.snowier.core.util.ZDateUtil;
import org.zfes.snowier.core.util.ZObjectUtil;
import org.zfes.snowier.core.util.ZAlert;
import org.zfes.snowier.core.util.ZAssert;
import org.zfes.snowier.common.dao.params.ParamMap;
import org.zfes.snowier.cloud.zbss.cms.content.service.ICmsContentAttachmentService;
import org.zfes.snowier.cloud.zbss.cms.content.service.ICmsContentChargeRecordService;
import org.zfes.snowier.cloud.zbss.cms.content.service.ICmsContentChargeService;
import org.zfes.snowier.cloud.zbss.cms.content.service.ICmsContentColumnService;
import org.zfes.snowier.cloud.zbss.cms.content.service.ICmsContentCountService;
import org.zfes.snowier.cloud.zbss.cms.content.service.ICmsContentGroupViewService;
import org.zfes.snowier.cloud.zbss.cms.content.service.ICmsContentOperateRecordService;
import org.zfes.snowier.cloud.zbss.cms.content.service.ICmsContentService;
import org.zfes.snowier.cloud.zbss.cms.content.service.ICmsContentTagService;
import org.zfes.snowier.cloud.zbss.cms.content.service.ICmsContentTxtService;
import org.zfes.snowier.cloud.zbss.cms.content.service.ICmsContentUserDefineAttrService;
import org.zfes.snowier.cloud.zbss.cms.model.dto.CmsModelDto;
import org.zfes.snowier.cloud.zbss.cms.model.service.ICmsModelService;
import org.zfes.snowier.cloud.zbss.cms.zconfig.ZConfig;
import org.zfes.snowier.cloud.zbss.cms.column.model.CmsColumn;
import org.zfes.snowier.cloud.zbss.cms.column.service.ICmsColumnService;
import org.zfes.snowier.cloud.zbss.cms.content.dao.CmsContentMapper;
import org.zfes.snowier.cloud.zbss.cms.content.dto.CmsContentCreateDto;
import org.zfes.snowier.cloud.zbss.cms.content.dto.CmsContentViewDto;
import org.zfes.snowier.cloud.zbss.cms.content.model.CmsContent;
import org.zfes.snowier.cloud.zbss.cms.content.model.CmsContentCharge;
import org.zfes.snowier.cloud.zbss.cms.content.model.CmsContentColumn;
import org.zfes.snowier.cloud.zbss.cms.content.model.CmsContentCount;
import org.zfes.snowier.cloud.zbss.cms.content.model.CmsContentGroupView;
import org.zfes.snowier.cloud.zbss.cms.content.model.CmsContentTxt;

import java.util.stream.Collectors;
import java.util.stream.Stream;
@Service
public class CmsContentServiceImpl implements ICmsContentService{
 	@Autowired
	private CmsContentMapper cmsContentMapper;
 	@Autowired
	private ICmsContentUserDefineAttrService cmsContentUserDefineAttrService;
 	
 	@Autowired
	private ICmsColumnService cmsColumnCountService;
 	@Autowired
	private ICmsModelService cmsModelService;
 	
 	@Autowired
	private ICmsContentTxtService cmsContentTxtService;
 	@Autowired
 	private ICmsContentTagService cmsContentTagService;
 	
 	@Autowired
 	private ICmsContentGroupViewService cmsContentGroupViewService;
 	@Autowired
 	private ICmsContentChargeService cmsContentChargeService;
 	
 	@Autowired
 	private ICmsContentColumnService cmsContentColumnService;
 	@Autowired
 	private ICmsContentAttachmentService cmsContentAttachmentService;
 	
 	@Autowired
 	private ICmsContentCountService cmsContentCountService;
 	@Autowired
 	private ICmsContentChargeRecordService cmsContentChargeRecordService;
 	
 	@Autowired
 	private ICmsContentOperateRecordService cmsContentOperateRecordService;
 	@Autowired
 	private ICmsColumnService cmsColumnService;

 	
 	//===========增
	@Transactional(rollbackFor=Exception.class)
 	@Override
	public void createCmsContent(CmsContentCreateDto contentCreateDto,Map<String ,String> userDefineAttrMap) {
		
		Long columnId=contentCreateDto.getResourceColumnId();
		ZAssert.notNull(columnId, "所属原始栏目未选择");
		
		String title=contentCreateDto.getTitle();
		ZAssert.notNull(title, "请填写标题");
		ZAssert.hasText(title, "请填写标题");
		
		//找到栏目---
		Optional<CmsColumn> columnOp=cmsColumnCountService.loadCmsColumnById(columnId);
		ZAssert.notEmpty(columnOp, "未查询到栏目数据");
		ZAssert.equals(columnOp.get().getStatus(), Byte.valueOf("1"), "该栏目已经被删除或者禁用");
		
		//找到栏目---
		Optional<CmsModelDto> cmsModelDtoOp = cmsModelService.loadCmsModelDtoById(contentCreateDto.getModelId());
		
		CmsContent cmsContent=new CmsContent();
		ZBeanUtil.setCreateInfo(cmsContent);
		ZBeanUtil.copy(contentCreateDto, cmsContent, true);
		
		cmsContent.setSiteId(ZConfig.siteId);
		
		//根据model的定义校验数据
		validateByModel(cmsModelDtoOp.get(), cmsContent, userDefineAttrMap) ;
		
		
		//创建content
		Long contentId=createCmsContent( cmsContent) ;
		//若为草稿，则修改状态
        if(userDefineAttrMap.containsKey("draft")) {
        	if(userDefineAttrMap.get("draft").equals("1"))
        		cmsContentMapper.updateStatus(contentId, Byte.valueOf("3"));//状态_D#-1删除，0初始提交/审核中，1 审核通过，2审核未通过,，3 草稿#
        }
		
		//产生linkurl
		String linkUrl=generateLinkUrl(columnId,contentId);
		//更新url
		cmsContentMapper.updateLinkUrl(cmsContent.getId(),linkUrl);
		
		//创建自定义字段 cms_content_user_define_attr
		cmsContentUserDefineAttrService.createOrUpdateUserDefineAttr(cmsContent.getId(), userDefineAttrMap);
		
		//创建副文本内容
		cmsContentTxtService.createCmsContentTxt(new CmsContentTxt( contentId, contentCreateDto.getContentTxt(), contentCreateDto.getContentTxt1(), contentCreateDto.getContentTxt2(),contentCreateDto.getContentTxt3()));
		
		
		//向cms_content_column表中添加记录
		CmsContentColumn contentColumn = new CmsContentColumn();
		ZBeanUtil.setCreateInfo(contentColumn);
		contentColumn.setColumnId(columnId);
		contentColumn.setContentId(contentId);
		cmsContentColumnService.createCmsContentColumn(contentColumn);
		
		//向cms_content_tag表中添加记录(同时修改cms_tag表中记录)
		if(userDefineAttrMap.containsKey("tagStr")) {
			//批量插入
			cmsContentTagService.createCmsContentTag(contentId,userDefineAttrMap.get("tagStr"),cmsContent.getSiteId());
		}
		//向cms_content_charge表中添加记录
		if(userDefineAttrMap.containsKey("charge")) {
			CmsContentCharge contentCharge = new CmsContentCharge();
			ZBeanUtil.setCreateInfo(contentCharge);
			contentCharge.setContentId(contentId);
			//收费
			if(userDefineAttrMap.get("charge").equals("1")) {
				contentCharge.setChargeReward(Byte.valueOf("1"));
				contentCharge.setChargeAmount(Double.valueOf(userDefineAttrMap.get("chargeAmount")));
				cmsContentChargeService.createCmsContentCharge(contentCharge);
			}
			//打赏
			if(userDefineAttrMap.get("charge").equals("1")) {
				contentCharge.setChargeReward(Byte.valueOf("2"));
				contentCharge.setRewardPattern(Byte.valueOf(userDefineAttrMap.get("rewardPattern")));
				
				//打赏方式：随机
				if(userDefineAttrMap.get("rewardPattern").equals("0")) {
					contentCharge.setRewardRandomMax(Double.valueOf(userDefineAttrMap.get("rewardRandomMax")));
					contentCharge.setRewardRandomMin(Double.valueOf(userDefineAttrMap.get("rewardRandomMin")));
				}
				
				//打赏方式：固定
				if(userDefineAttrMap.get("rewardPattern").equals("1")) {
					contentCharge.setChargeAmount(Double.valueOf("chargeAmount"));
				}
				cmsContentChargeService.createCmsContentCharge(contentCharge);	
			}
		}
		
		//向cms_content_group_view表中添加记录
		if(userDefineAttrMap.containsKey("viewGroupIds")) {
			CmsContentGroupView contentGroupView = new CmsContentGroupView();
			ZBeanUtil.setCreateInfo(contentGroupView);
			contentGroupView.setContentId(contentId);
			
			//取出groupIds
			String groupIds=userDefineAttrMap.get("viewGroupIds");
			List<Long> viewGroupIdList=Arrays.asList(groupIds.split(",")).stream().map(s->Long.parseLong(s.trim())).collect(Collectors.toList());
			
			//批量插入
			List<CmsContentGroupView> contentGroupViewList=new ArrayList<CmsContentGroupView>();
			for(int i=0;i<viewGroupIdList.size();i++) {
				contentGroupView.setGroupId(viewGroupIdList.get(i));
				contentGroupViewList.add(contentGroupView);
			}
			cmsContentGroupViewService.createCmsContentGroupViewBatch(contentGroupViewList);
		}
		//向cms_content_count添加记录
		CmsContentCount contentCount = new CmsContentCount();
		ZBeanUtil.setCreateInfo(contentCount);
		contentCount.setContentId(contentId);
		cmsContentCountService.createCmsContentCount(contentCount);
		
	}

	@Transactional(rollbackFor=Exception.class)
 	@Override
	public Long createCmsContent(CmsContent cmsContent) {
		
		ZBeanUtil.setCreateInfo(cmsContent);
		
		cmsContent.setStatus(Byte.valueOf("0"));//状态_D#-1删除，0初始提交/审核中，1 审核通过，2审核未通过,，3 草稿#
		
		ZBeanUtil.validateBean(cmsContent);

		cmsContentMapper.insertSelective(cmsContent);
		return cmsContent.getId();
	
	}
	//================删
	@Transactional(rollbackFor=Exception.class)
	@Override
	public void deleteCmsContent(Long contentId) {
		ZAssert.notNull(contentId, "请选择要操作的数据");
		cmsContentMapper.deleteByPrimaryKey(contentId);
		
		//cms_content_column表记录逻辑删除
		cmsContentColumnService.setCmsContentColumnStatusByContentId(contentId,Byte.valueOf("-1"));
		//cms_content_attachment表记录逻辑删除
		cmsContentAttachmentService.setCmsContentAttachmentStatusByContentId(contentId, Byte.valueOf("-1"));
		//cms_content_charge表记录逻辑删除
		cmsContentChargeService.setCmsContentChargeStatusByContentId(contentId, Byte.valueOf("-1"));
		//cms_content_group_view表记录物理删除
		cmsContentGroupViewService.loadCmsContentGroupViewByContentId(contentId);
		//cms_content_contet_txt表记录逻辑删除
		cmsContentTxtService.setCmsContentTxtStatusByContentId(contentId, Byte.valueOf("-1"));
		//cms_content_count表记录逻辑删除
		cmsContentCountService.setCmsContentCountStatusByContentId(contentId, Byte.valueOf("-1"));
		//cms_content_charge_record表记录逻辑删除
		cmsContentChargeRecordService.setCmsContentChargeRecordStatusByContentId(contentId, Byte.valueOf("-1"));
		//cms_content_operate_record表记录逻辑删除
		cmsContentOperateRecordService.setCmsContentOperateRecordStatusByContentId(contentId, Byte.valueOf("-1"));
		//cms_content_user_define_attr表记录逻辑删除
		cmsContentUserDefineAttrService.setCmsContentUserDefineAttrStatusByContentId(contentId, Byte.valueOf("-1"));
	    //cms_content_tag表记录物理删除(引用次数-1)
		cmsContentTagService.deleteCmsContentTagByContentId(contentId);		
	}
		
		
	//===============================改
	@Transactional(rollbackFor=Exception.class)
	@Override
	public void updateCmsContent(Long contentId,CmsContentCreateDto contentCreateDto,Map<String ,String> userDefineAttrMap) {
		ZAssert.notNull(contentId, "内容Id参数错误");
		Long columnId=contentCreateDto.getResourceColumnId();
		ZAssert.notNull(columnId, "所属原始栏目未选择");
		
		String title=contentCreateDto.getTitle();
		ZAssert.notNull(title, "请填写标题");
		ZAssert.hasText(title, "请填写标题");
		
		//找到栏目---
		Optional<CmsColumn> columnOp=cmsColumnCountService.loadCmsColumnById(columnId);
		ZAssert.notEmpty(columnOp, "未查询到栏目数据");
		ZAssert.equals(columnOp.get().getStatus(), Byte.valueOf("1"), "该栏目已经被删除或者禁用");
		
		//找到栏目---
		Optional<CmsModelDto> cmsModelDtoOp = cmsModelService.loadCmsModelDtoById(contentCreateDto.getModelId());
		
		CmsContent cmsContent=new CmsContent();
		ZBeanUtil.setCreateInfo(cmsContent);
		ZBeanUtil.copy(contentCreateDto, cmsContent, true);
		
		cmsContent.setSiteId(ZConfig.siteId);
		
		//根据model的定义校验数据
		validateByModel(cmsModelDtoOp.get(), cmsContent, userDefineAttrMap) ;
		
		//更新cms_content
		cmsContentMapper.update(cmsContent);
		
		//更新自定义字段 cms_content_user_define_attr
		
		cmsContentUserDefineAttrService.createOrUpdateUserDefineAttr(contentId, userDefineAttrMap);
				
		//更新副文本内容
		cmsContentTxtService.setCmsContentTxtStatusByContentId(contentId, Byte.valueOf("-1"));
		cmsContentTxtService.createCmsContentTxt(new CmsContentTxt( contentId, contentCreateDto.getContentTxt(), contentCreateDto.getContentTxt1(), contentCreateDto.getContentTxt2(),contentCreateDto.getContentTxt3()));
						
		//更新cms_content_tag表中记录
		if(userDefineAttrMap.containsKey("tagStr")) {
			//逻辑删除原来的content_tag
			
			//添加新的content_tag
			cmsContentTagService.createCmsContentTag(contentId, userDefineAttrMap.get("tagStr"), cmsContent.getSiteId());
		}
		//更新cms_content_charge表中记录
		if(userDefineAttrMap.containsKey("charge")) {
			
			CmsContentCharge contentCharge =cmsContentChargeService.loadCmsContentChargeByContentId(contentId).get();
			//收费
			if(userDefineAttrMap.get("charge").equals("1")) {
				contentCharge.setChargeReward(Byte.valueOf("1"));
				contentCharge.setChargeAmount(Double.valueOf(userDefineAttrMap.get("chargeAmount")));
				cmsContentChargeService.updateCmsContentCharge(contentCharge);
			}
			//打赏
			if(userDefineAttrMap.get("charge").equals("2")) {
				contentCharge.setChargeReward(Byte.valueOf("2"));
				contentCharge.setRewardPattern(Byte.valueOf(userDefineAttrMap.get("rewardPattern")));
						
				//打赏方式：随机
				if(userDefineAttrMap.get("rewardPattern").equals("0")) {
					contentCharge.setRewardRandomMax(Double.valueOf(userDefineAttrMap.get("rewardRandomMax")));
					contentCharge.setRewardRandomMin(Double.valueOf(userDefineAttrMap.get("rewardRandomMin")));
				}
						
				//打赏方式：固定
				if(userDefineAttrMap.get("rewardPattern").equals("1")) {
					contentCharge.setChargeAmount(Double.valueOf("chargeAmount"));
				}
				cmsContentChargeService.updateCmsContentCharge(contentCharge);	
			}
		}
		//更新cms_content_group_view表记录
		if(userDefineAttrMap.containsKey("viewGroupIds")) {
			//删除原有记录
			cmsContentGroupViewService.deleteCmsContentGroupViewByContentId(contentId);
			//添加新的记录
			CmsContentGroupView contentGroupView = new CmsContentGroupView();
			ZBeanUtil.setCreateInfo(contentGroupView);
			contentGroupView.setContentId(contentId);
			
			//取出groupIds
			String groupIds=userDefineAttrMap.get("viewGroupIds");
			List<Long> viewGroupIdList=Arrays.asList(groupIds.split(",")).stream().map(s->Long.parseLong(s.trim())).collect(Collectors.toList());
			
			//批量插入
			List<CmsContentGroupView> contentGroupViewList=new ArrayList<CmsContentGroupView>();
			for(int i=0;i<viewGroupIdList.size();i++) {
				contentGroupView.setGroupId(viewGroupIdList.get(i));
				contentGroupViewList.add(contentGroupView);
			}
			cmsContentGroupViewService.createCmsContentGroupViewBatch(contentGroupViewList);
		}
	}
	@Transactional(rollbackFor=Exception.class)
	@Override
	public void updateCmsContent(CmsContent cmsContent) {
		ZBeanUtil.validateBean(cmsContent);
		cmsContent.setUpdateTime(ZDateUtil.newDate());
		cmsContentMapper.updateByPrimaryKeySelective(cmsContent);
	}
	@Transactional(rollbackFor=Exception.class)
	@Override
	public void setCmsContentStatus(Long id, Byte status) {
		ZAssert.notNull(id, "请选择要操作的数据");
		ZAssert.notNull(status, "状态参数错误");
		if(!Stream.of(new Byte[] {-1,0,1}).anyMatch(val->val.equals(status))) {
			ZAlert.serviceLogicalError("状态参数错误");
		}
		cmsContentMapper.updateStatus( id,  status) ;
	}
	
	@Transactional(rollbackFor=Exception.class,readOnly=false)
	@Override
	public void updateAddViewCount(Long id, Integer countz) {
		if(ZObjectUtil.isNull(id)||ZObjectUtil.isNull(countz)||countz==0) {
			return ;
		}
		 cmsContentMapper.updateAddCommentCount(id, countz);
	}

	@Transactional(rollbackFor=Exception.class,readOnly=false)
	@Override
	public void updateAddFavoriteCount(Long id, Integer countz) {
		if(ZObjectUtil.isNull(id)||ZObjectUtil.isNull(countz)||countz==0) {
			return ;
		}
		  cmsContentMapper.updateAddFavoriteCount(id, countz);
	}

	@Transactional(rollbackFor=Exception.class,readOnly=false)
	@Override
	public void updateAddUpCount(Long id, Integer countz) {
		if(ZObjectUtil.isNull(id)||ZObjectUtil.isNull(countz)||countz==0) {
			return ;
		}
		  cmsContentMapper.updateAddUpCount(id, countz);
	}

	@Transactional(rollbackFor=Exception.class,readOnly=false)
	@Override
	public void updateAddCommentCount(Long id, Integer countz) {
		if(ZObjectUtil.isNull(id)||ZObjectUtil.isNull(countz)||countz==0) {
			return ;
		}
		  cmsContentMapper.updateAddCommentCount(id, countz);
	}

	@Transactional(rollbackFor=Exception.class,readOnly=false)
	@Override
	public void updateAddForwardCount(Long id, Integer countz) {
		if(ZObjectUtil.isNull(id)||ZObjectUtil.isNull(countz)||countz==0) {
			return ;
		}
		  cmsContentMapper.updateAddForwardCount(id, countz);
	}

	@Transactional(rollbackFor=Exception.class,readOnly=false)
	@Override
	public void updateAddShareCount(Long id, Integer countz) {
		if(ZObjectUtil.isNull(id)||ZObjectUtil.isNull(countz)||countz==0) {
			return ;
		}
		  cmsContentMapper.updateAddShareCount(id, countz);
	}

	@Transactional(rollbackFor=Exception.class,readOnly=false)
	@Override
	public void updateAddDownloadcount(Long id, Integer countz) {
		if(ZObjectUtil.isNull(id)||ZObjectUtil.isNull(countz)||countz==0) {
			return ;
		}
		  cmsContentMapper.updateAddDownloadcount(id, countz);
	}
	
	//===============查
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public Optional<CmsContent> loadCmsContentById(Long id) {
		if(id!=null){
			return Optional.ofNullable(cmsContentMapper.selectByPrimaryKey(id));
		}
		return Optional.empty();
		
	}
	
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public DataSet loadCmsContentDataSet(Map<String, Object> params) {
		ParamMap pm=ParamMap.filterParam(params);
		DataSet ds=DataSet.newDS2(cmsContentMapper.selectListCount(pm), cmsContentMapper.selectMapListPage(pm));
		return ds;
	}
	
	@Transactional(rollbackFor=Exception.class,readOnly=true)	
	@Override
	public Map<List<CmsContentViewDto>,Integer> loadCmsContentViewDtoByTagId(Long tagId) {
		
		List<Long> contentIdList = cmsContentTagService.selectContentIdListByTagId(tagId);
		List<CmsContentViewDto> contentViewDtoList=new ArrayList<CmsContentViewDto>();
		Map<List<CmsContentViewDto>,Integer> map=new HashMap<List<CmsContentViewDto>,Integer>();
		
		//tag标签为null
		if(tagId==null) {
			map.put(contentViewDtoList, 0);
			return map;
		}
		//tagId不为null
		CmsContent cmsContent = new CmsContent();
		CmsContentViewDto contentViewDto = new CmsContentViewDto();
		String columnName="";
		for(int i=0;i<contentIdList.size();i++) {
			//获取contentViewDto属性参数
			cmsContent=cmsContentMapper.selectByPrimaryKey(contentIdList.get(i));
			Long columnId=cmsContentColumnService.loadCmsContentColumnByContentId(contentIdList.get(i)).get().getColumnId();
			columnName=cmsColumnService.loadCmsColumnById(columnId).get().getColumnName();
			
			//生成createViewDto
			contentViewDto.setCmsContent(cmsContent);
			contentViewDto.setColumnName(columnName);
			contentViewDtoList.add(contentViewDto);
		}
		//生成map
		map.put(contentViewDtoList, contentViewDtoList.size());
		return map;
	}
    
	
}